package com.itheima.health.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.health.service.ExtLock;
import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

import java.util.concurrent.CountDownLatch;

/**
 * @Author gentleman Ma
 * @Date created in 2020/1/5
 * @description 分布式锁服务接口实现类
 * @Version 1.0
 */
@Service
@Slf4j
public class ExtLockImpl implements ExtLock {

    private static final String CONNECTION="127.0.0.1:2181";

    protected ZkClient zkClient = new ZkClient(CONNECTION);

    CountDownLatch countDownLatch = null;

    private String lockPath = "/lockPath";



    @Override
    public boolean tryLock() {

       try {
           zkClient.createEphemeral(lockPath);
           log.debug("[获取锁>>>>>>>>>]");
           return true;
       } catch (Exception e){
           // 如果失败 直接catch
           log.error("",e);
           return false;
       }
    }


    //获取锁
    @Override
    public boolean getLock() {
        try {
            zkClient.createEphemeral(lockPath);
            return true;
        } catch (Exception e){
            log.error("",e);
            return false;
        }
    }
    @Override
    public void unLock() {

    }

    @Override
    public void waitLock() {
        IZkDataListener iZkDataListener = new IZkDataListener() {

            //节点被修改
            @Override
            public void handleDataChange(String s, Object o) throws Exception {

            }

            //节点被删除
            @Override
            public void handleDataDeleted(String s) throws Exception {
                if (countDownLatch != null){
                    // 计数器为0的情况，await 后面的继续执行
                    countDownLatch.countDown();
                }
            }
        };
        //监听事件通知
        zkClient.subscribeChildChanges(lockPath, (IZkChildListener) iZkDataListener);
        //如果 检查出 已经被创建了 就new 然后进行等待
        if (zkClient.exists(lockPath)){
            countDownLatch = new CountDownLatch(1);
            try{
                //等待时候 就不往下走了   当为0 时候 后面的继续执行
                countDownLatch.wait();
            } catch (Exception e){
                log.error("",e);
            }
        }
        zkClient.unsubscribeDataChanges(lockPath,iZkDataListener);
    }

}
